package com.tanhua.sso.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.tanhua.common.utils.JwtUtils;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.dubbo.api.HuanXinApi;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.dubbo.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @DubboReference(version = "1.0.0")
    private UserApi userApi;

    @DubboReference(version = "1.0.0")
    private HuanXinApi huanXinApi;

    @Autowired
    private RSAService rsaService;
    //redis冻结前缀
    private static final String CACHE_KEY_FREEZE_PREFIX = "FREEZE_";

    public Object login(String phone, String code) {
        //判断手机号或者验证码是否为空
        if(StrUtil.isAllNotEmpty(phone,code)){
            //校验验证码是否正确
            String redisKey = SmsService.REDIS_CODE + phone;
            String redisData = this.redisTemplate.opsForValue().get(redisKey);
            if (!StrUtil.equals(code, redisData)) {
                return ErrorResult.builder().errCode("500")
                        .errMessage("验证码错误，请重新输入！").build();
            }

            //验证码正确，需要将验证码删除，只能使用一次
            this.redisTemplate.delete(redisKey);

            //判断是否为新用户
            User user = this.userApi.queryByMobile(phone);
            Long userId;
            boolean isNew = false;
            if (null == user) {
                //新用户，需要进行注册
                userId = this.userApi.save(phone);
                isNew = true;

            //注册环信用户
            Boolean result = this.huanXinApi.register(user.getId());
            if (!result) {
                //注册环信失败，记录日志
                log.error("注册环信用户失败~ userId = " + user.getId());
            }
        } else {
            userId = user.getId();
            //判断用户是否被冻结
            String freezeKey=CACHE_KEY_FREEZE_PREFIX+userId;
            String redisFreeze = this.redisTemplate.opsForValue().get(freezeKey);
            if (StrUtil.isNotEmpty(redisFreeze)){
                Long expire = this.redisTemplate.getExpire(freezeKey, TimeUnit.HOURS);
                return ErrorResult.builder().errCode("400")
                        .errMessage("您的账户已被冻结,请联系管理员,剩余冻结时间为:"+expire+"小时").build();
            }
        }

        //登录成功，生成token JWT
        Map<String, Object> claims = MapUtil.builder(new HashMap<String, Object>()).put("userId", userId).build();
        String token = JwtUtils.createToken(claims, this.rsaService.getPrivateKeyStr(), 24);

            try {
                //发消息给其他系统
                Map<Object, Object> msgMap = MapUtil.builder().put("userId", userId)
                        .put("date", System.currentTimeMillis())
                        .put("isNew", isNew).build();
                this.rocketMQTemplate.convertAndSend("tanhua-sso-login", msgMap);
            } catch (Exception e) {
                log.error("发送消息失败！userId = {}, phone = {}", userId, phone, e);
            }

            return MapUtil.builder().put("token", token)
                    .put("isNew", isNew).build();
        }
        //手机号或者验证码为空,防止用户验证码失效，用户没有输入验证码登录的情况
        return ErrorResult.builder().errCode("402").errMessage("请输入正确的登录格式哦~").build();
    }

    /**
     * 校验token，如果校验通过，返回用户id
     *
     * @param token
     * @return
     */
    public Long checkToken(String token) {
        Map<String, Object> map = JwtUtils.checkToken(token, this.rsaService.getPublicKeyStr());
        if (CollUtil.isNotEmpty(map)) {
            return Convert.toLong(map.get("userId"));
        }
        return null;
    }

    public User queryUserByUserId(Long userId) {
        User user = this.userApi.queryById(userId);
        return user;
    }

    public Boolean updateLogin( String code,User user) {

        //校验验证码是否正确
        String redisKey = SmsService.REDIS_CODE + user.getMobile();
        String redisData = this.redisTemplate.opsForValue().get(redisKey);
        if (!StrUtil.equals(code, redisData)) {
            return false;
        }

        //验证码正确，需要将验证码删除，只能使用一次
        this.redisTemplate.delete(redisKey);

        return true;
    }

    public Object updatePhone(Long userId, String phone) {
        User user = this.userApi.queryById(userId);
        if(ObjectUtil.isEmpty(user)){
            //用户为空，返回失败
            return ErrorResult.builder().errCode("401").errMessage("用户不存在").build();
        }
        //查询新手机号是否已经被注册
        User newPhoneUser = this.userApi.queryByMobile(phone);
        if(ObjectUtil.isNotEmpty(newPhoneUser)){
            //手机号已经被注册
            return ErrorResult.builder().errCode("402").errMessage("改手机号已经注册").build();
        }

        //手机号没注册
        user.setMobile(phone);
        return  this.userApi.updatePhone(user) == 1;
    }


}
